package com.yuncheng.spcyApi.config;

import com.yuncheng.spcyApi.constant.file.SpcyMinioConstant;
import com.yuncheng.exception.BusinessException;
import com.yuncheng.spcyApi.utils.StringPatternUtils;
import groovy.util.logging.Slf4j;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import utils.Util;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * minio 工具类
 */
@Component
@Slf4j
public class SpcyMinioUtils {

    private static final Logger log = LoggerFactory.getLogger(SpcyMinioUtils.class);

    @Resource
    private SpcyMinioConfig prop;

    @Resource
    private MinioClient minioClient;

    @Resource
    private SpcyMinioConstant spcyMinioConstant;

    /**
     * 删除文件夹下的所有文件
     @param ml 文件夹名称(后缀不加/)
     @throws Exception
     */
    public void removeObjects(String ml) {
        try {
            Iterable<Result<Item>> list = listObjects(prop.getBucketName(), ml);

            for(Result<Item> item : list){
                minioClient.removeObject(RemoveObjectArgs
                        .builder()
                        .bucket(prop.getBucketName())
                        .object(item.get().objectName())
                        .build());
//                System.out.println(item.get().objectName()); // objectName/xxx
                /*String[] split = item.get().objectName().split("/");
                System.out.println("1: "+split[1]);

                Iterable<Result<Item>> list2 = listObjects(prop.getBucketName()+"/"+split[0],split[1]);
                for(Result<Item> item2 : list2){
                    System.out.println("2: "+item2.get().objectName());
                }*/
            }
        }catch (Exception e){
            throw new BusinessException("文件删除失败！");
        }
    }

    /**
     * 获取指定目录下的所有文件夹及文件
     * @param ml 文件夹名称(后缀不加/)
     * */
    public Iterable<Result<Item>> listObjects(String ml){
        String objectNames = ml + "/";
        Iterable<Result<Item>> list = minioClient.listObjects(ListObjectsArgs
                .builder()
                .bucket(prop.getBucketName())
                .prefix(objectNames)
                .recursive(false)
                .build());

        return list;
    }

    /**
     * 获取指定目录下的所有文件夹及文件
     * @param bucketName 文件桶名称
     * @param ml 文件夹名称 (后缀不加/)
     * */
    private Iterable<Result<Item>> listObjects(String bucketName, String ml){
        String objectNames = ml + "/";
        Iterable<Result<Item>> list = minioClient.listObjects(ListObjectsArgs
                .builder()
                .bucket(bucketName)
                .prefix(objectNames)
                .recursive(false)
                .build());

        return list;
    }

    /**
     * 查看存储bucket是否存在
     * @return boolean
     */
    public Boolean bucketExists(String bucketName) {
        Boolean found;
        try {
            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return found;
    }

    /**
     * 创建存储bucket
     * @return Boolean
     */
    public Boolean makeBucket(String bucketName) {
        try {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 删除存储bucket
     * @return Boolean
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder()
                    .bucket(bucketName)
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
    /**
     * 获取全部bucket
     */
    public List<Bucket> getAllBuckets() {
        try {
            List<Bucket> buckets = minioClient.listBuckets();
            return buckets;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件上传
     *
     * @param file 文件
     * @param objectName 不能以 第一个字符为斜杠
     * @return Boolean
     */
    public String uploadFile(MultipartFile file,String objectName) {
        /*String originalFilename = file.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)){
            throw new RuntimeException();
        }*/

        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        /*String nowDay = DateUtil.today(); // 获取当前日期 yyyy-MM-dd
        String objectName = ml + "/" + nowDay + "/" + GetUuIdUtils.NotReplaceUuId() + originalFilename.substring(originalFilename.lastIndexOf("."));*/

        try {
            /*PutObjectArgs objectArgs = PutObjectArgs
                    .builder()
                    .bucket(prop.getBucketName())
                    .object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            // 文件名称相同会覆盖
            minioClient.putObject(objectArgs);*/

            this.putMultipartFile(prop.getBucketName(),objectName,file);

        } catch (Exception e) {
            log.error("minio-文件上传失败：{}", e.getMessage());
            return null;
        }

        return objectName;
    }

    /**
     * 文件上传
     *
     * @param file 文件
     * @param objectName 不能以 第一个字符为斜杠
     * @return Boolean
     */
    public String uploadFile(MultipartFile file,String bucketName,String objectName) {
        if (StringUtils.isBlank(bucketName)){
            bucketName = prop.getBucketName();
        }
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)){
            throw new RuntimeException();
        }

        /*String nowDay = DateUtil.today(); // 获取当前日期 yyyy-MM-dd
        String objectName = ml + "/" + nowDay + "/" + GetUuIdUtils.NotReplaceUuId() + originalFilename.substring(originalFilename.lastIndexOf("."));*/

        try {
            /*PutObjectArgs objectArgs = PutObjectArgs
                    .builder()
                    .bucket(prop.getBucketName())
                    .object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            // 文件名称相同会覆盖
            minioClient.putObject(objectArgs);*/

            this.putMultipartFile(bucketName,objectName,file);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return objectName;
    }

    /**
     * 预览文件
     * @param fileName 文件存储路径
     * @return
     */
    public String preview(String fileName){
        fileName = this.getFileUrlRemoveFirstIndex(fileName);

        // 查看文件地址
        GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs()
                .builder()
                .bucket(prop.getBucketName())
                .object(fileName)
                .method(Method.GET)
                .build();
        try {
            String url = minioClient.getPresignedObjectUrl(build);
            return url;
        } catch (Exception e) {
            return "";
//            throw new BusinessException("预览文件失败："+e.getMessage());
        }
    }

    /**
     * 文件下载
     * @param fileName 文件存储路径
     * @param res response
     * @return Boolean
     */
    public void download(String fileName, HttpServletResponse res) {
        fileName = this.getFileUrlRemoveFirstIndex(fileName);

        GetObjectArgs objectArgs = GetObjectArgs
                .builder()
                .bucket(prop.getBucketName())
                .object(fileName)
                .build();
        try (InputStream stream = minioClient.getObject(objectArgs)){
                byte[] bf = new byte[1024];
                int length;
//                res.reset();
//                res.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
                res.setContentType(Util.getContenTypeByWjhz(Util.getWjHz(fileName)));
                res.setCharacterEncoding("UTF-8");
                OutputStream outputStream = res.getOutputStream();
                // 输出文件
                while ((length = stream.read(bf)) > 0) {
                    outputStream.write(bf, 0, length);
                }
                // 关闭输出流
                outputStream.flush();
                outputStream.close();
            /*byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
                while ((len=response.read(buf))!=-1){
                    os.write(buf,0,len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                // 设置强制下载不打开
                // res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                try (ServletOutputStream stream = res.getOutputStream()){
                    stream.write(bytes);
                    stream.flush();
                }
            }*/
        } catch (Exception e) {
//            throw new BusinessException("文件下载失败："+e.getMessage());
            log.error("文件下载失败: {}", e.getMessage());

            res.setContentType("text/html");
            res.setCharacterEncoding("UTF-8");
            PrintWriter writer = null;
            try {
                writer = res.getWriter();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            writer.println("文件下载失败！"+e.getMessage());
            writer.close(); // 不要忘记关闭PrintWriter
            return;
        }
    }

    /**
     * 文件下载
     * @param fileName 文件存储路径
     * @param res response
     * @return Boolean
     */
    public void download(String fileName, String bucketName, HttpServletResponse res) {
        fileName = this.getFileUrlRemoveFirstIndex(fileName);
        if (StringUtils.isBlank(bucketName)){
            bucketName = prop.getBucketName();
        }

        GetObjectArgs objectArgs = GetObjectArgs
                .builder()
                .bucket(bucketName)
                .object(fileName)
                .build();
        try (InputStream stream = minioClient.getObject(objectArgs)){
            byte[] bf = new byte[1024];
            int length;
//            res.reset();
//            res.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            res.setContentType(Util.getContenTypeByWjhz(Util.getWjHz(fileName)));
            res.setCharacterEncoding("UTF-8");
            OutputStream outputStream = res.getOutputStream();
            // 输出文件
            while ((length = stream.read(bf)) > 0) {
                outputStream.write(bf, 0, length);
            }
            // 关闭输出流
            outputStream.flush();
            outputStream.close();
            /*byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){
                while ((len=response.read(buf))!=-1){
                    os.write(buf,0,len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                // 设置强制下载不打开
                // res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                try (ServletOutputStream stream = res.getOutputStream()){
                    stream.write(bytes);
                    stream.flush();
                }
            }*/
        } catch (Exception e) {
            throw new BusinessException("文件下载失败："+e.getMessage());
        }
    }

    /**
     * 根据文件全路径获取文件流
     *
     * @param objectName 文件名称
     * @return 文件流
     */
    public InputStream getObject(String objectName) {
        return this.getObject(prop.getBucketName(), objectName);
    }

    /**
     * 根据文件桶和文件全路径获取文件流
     *
     * @param bucketName 桶名称
     * @param objectName 文件名
     * @return 文件流
     */
    public InputStream getObject(String bucketName, String objectName) {
        objectName = this.getFileUrlRemoveFirstIndex(objectName);
        try {
            return minioClient.getObject(
                            GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build());
        } catch (Exception e) {
//            throw new RuntimeException("根据文件名获取流失败!", e);
            log.error("根据文件名获取流失败! {}", e.getMessage());
            return null;
        }
    }

    /**
     * 根据url获取文件流
     *
     * @param url 文件URL
     * @return 文件流
     */
    public InputStream getObjectByUrl(String url) {
        try {
            return new URL(url).openStream();
        } catch (IOException e) {
            throw new RuntimeException("根据URL获取流失败!", e);
        }
    }

    /**
     * 查看文件对象
     * @return 存储bucket内文件对象信息
     */
    public List<Item> listObjects() {
        Iterable<Result<Item>> results = minioClient.listObjects(
                ListObjectsArgs.builder().bucket(prop.getBucketName()).build());
        List<Item> items = new ArrayList<>();
        try {
            for (Result<Item> result : results) {
                items.add(result.get());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return items;
    }

    /**
     * 删除
     * @param fileName 文件存储路径
     * @return
     * @throws Exception
     */
    public boolean remove(String fileName){
        fileName = this.getFileUrlRemoveFirstIndex(fileName);

        try {
            minioClient.removeObject(RemoveObjectArgs
                    .builder()
                    .bucket(prop.getBucketName())
                    .object(fileName)
                    .build());
        }catch (Exception e){
            return false;
        }
        return true;
    }

    /**
     * 删除文件
     *
     * @param objectName 文件名称
     */
    public boolean removeObject(String objectName) {
        try {
            this.removeObject(prop.getBucketName(), objectName);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 删除文件
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     */
    public boolean removeObject(String bucketName, String objectName) {
        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucketName).object(objectName).build());
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 获取文件信息, 如果抛出异常则说明文件不存在
     *
     * @param bucketName bucket名称
     * @param objectName 文件名称
     * @throws Exception https://docs.minio.io/cn/java-client-api-reference.html#statObject
     */
    public StatObjectResponse getObjectInfo(String bucketName, String objectName) throws Exception {
        return minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
    }

    /**
     * 判断文件夹是否存在
     *
     * @param folderName 文件夹名称
     * @return true存在, 反之
     */
    public Boolean checkFolderIsExist(String folderName) {
        return this.checkFolderIsExist(prop.getBucketName(), folderName);
    }

    /**
     * 判断文件是否存在
     *
     * @param bucketName 桶名称
     * @param objectName 文件名称, 如果要带文件夹请用 / 分割, 例如 /help/index.html
     * @return true存在, 反之
     */
    public Boolean checkFileIsExist(String bucketName, String objectName) {
        try {
            minioClient.statObject(
                    StatObjectArgs.builder().bucket(bucketName).object(objectName).build()
            );
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 判断文件夹是否存在
     *
     * @param bucketName 桶名称
     * @param folderName 文件夹名称
     * @return true存在, 反之
     */
    public Boolean checkFolderIsExist(String bucketName, String folderName) {
        try {
            Iterable<Result<Item>> results = minioClient.listObjects(
                    ListObjectsArgs
                            .builder()
                            .bucket(bucketName)
                            .prefix(folderName)
                            .recursive(false)
                            .build());
            for (Result<Item> result : results) {
                Item item = result.get();
                if (item.isDir() && folderName.equals(item.objectName())) {
                    return true;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }


    /**
     * 上传MultipartFile通用方法
     *
     * @param bucketName 桶名称
     * @param objectName 文件名
     * @param file       文件
     */
    private void putMultipartFile(String bucketName, String objectName, MultipartFile file) {
        InputStream stream = null;
        try {
            stream = file.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException("文件流获取错误", e);
        }
        try {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .contentType(file.getContentType())
                            .stream(stream, stream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException("文件流上传错误", e);
        }
        try {
            stream.close();
        } catch (IOException e) {
            throw new RuntimeException("关闭文件流错误", e);
        }
    }

    /**
     * 上传InputStream通用方法
     *
     * @param objectName 文件名
     * @param stream     文件流
     */
    private void putInputStream(String objectName, InputStream stream, String contentType) {
        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        try {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(prop.getBucketName())
                            .object(objectName)
                            .contentType(contentType)
                            .stream(stream, stream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException("文件流上传错误", e);
        }
    }

    /**
     * 上传InputStream通用方法
     *
     * @param bucketName 桶名称
     * @param objectName 文件名
     * @param stream     文件流
     */
    private void putInputStream(String bucketName, String objectName, InputStream stream, String contentType) {
        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        try {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .contentType(contentType)
                            .stream(stream, stream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException("文件流上传错误", e);
        }
    }

    /**
     * 上传 bytes 通用方法
     *
     * @param bucketName 桶名称
     * @param objectName 文件名
     * @param bytes      字节编码
     */
    private void putBytes(String bucketName, String objectName, byte[] bytes, String contentType) {
        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        // 字节转文件流
        InputStream stream = new ByteArrayInputStream(bytes);
        try {
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .contentType(contentType)
                            .stream(stream, stream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException("文件流上传错误", e);
        }
    }

    /**
     * 上传 file 通用方法
     *
     * @param objectName  文件名
     * @param file        文件
     * @param wjhz 文件后缀
     */
    public void putFile(String objectName, File file, String wjhz) {
        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            String contentType = Util.getContenTypeByWjhz(wjhz);
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(prop.getBucketName())
                            .object(objectName)
                            .contentType(contentType)
                            .stream(fileInputStream, fileInputStream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException("文件上传错误", e);
        }
        try {
            fileInputStream.close();
        } catch (IOException e) {
            throw new RuntimeException("文件流关闭错误",e);
        }
    }

    /**
     * 上传 file 通用方法
     *
     * @param objectName  文件名
     * @param file        文件
     * @param wjhz 文件后缀
     */
    public boolean putFlagFile(String objectName, File file, String wjhz) {
        boolean flag = true;
        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            String contentType = Util.getContenTypeByWjhz(wjhz);
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(prop.getBucketName())
                            .object(objectName)
                            .contentType(contentType)
                            .stream(fileInputStream, fileInputStream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            log.error("上传路径：{}; 被上传文件路径：{}", objectName, file.getAbsolutePath());
            log.error("minio文件上传错误：{}", e.getMessage());
            flag = false;
        }
        try {
            if (fileInputStream != null) {
                fileInputStream.close();
            }
        } catch (IOException e) {
            log.error("文件流关闭错误：{}", e.getMessage());
//            flag = false;
        }

        return flag;
    }

    /**
     * 上传 file 通用方法
     *
     * @param bucketName  桶名称
     * @param objectName  文件名
     * @param file        文件
     * @param contentType 文件类型, 例如 image/jpeg: jpg图片格式, 详细可看: https://www.runoob.com/http/http-content-type.html
     */
    private void putFile(String bucketName, String objectName, File file, String contentType) {
        objectName = this.getFileUrlRemoveFirstIndex(objectName);

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .contentType(contentType)
                            .stream(fileInputStream, fileInputStream.available(), -1)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException("文件上传错误", e);
        }
    }

    /************************************[行政审批 - 文件下载 ]********************************************************************/

    public MinioClient xzspMinioClient() {
        return MinioClient.builder()
                .endpoint(spcyMinioConstant.MINIO_URL)
                .credentials(spcyMinioConstant.MINIO_NAME, spcyMinioConstant.MINIO_PWD)
                .build();
    }

    /**
     * 下载文件-行政审批
     * @param fileName 文件存储路径
     * @param res
     */
    public void downLoadXzspFile(String fileName, HttpServletResponse res){
        String subFileUrl = this.XzspFileUrl(fileName);

        GetObjectArgs objectArgs = GetObjectArgs
                .builder()
                .bucket(spcyMinioConstant.MINIO_BUCKET_XZXK)
                .object(subFileUrl)
                .build();
        try (InputStream stream = this.xzspMinioClient().getObject(objectArgs)){
            byte[] bf = new byte[1024];
            int length;
//            res.reset();
//            res.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            res.setContentType(Util.getContenTypeByWjhz(Util.getWjHz(fileName)));
            res.setCharacterEncoding("UTF-8");
            OutputStream outputStream = res.getOutputStream();
            // 输出文件
            while ((length = stream.read(bf)) > 0) {
                outputStream.write(bf, 0, length);
            }
            // 关闭输出流
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            throw new BusinessException("文件下载错误："+e.getMessage());
        }
    }

    /**
     * 下载文件-行政审批(自定义)
     * @param subFileUrl 文件存储路径
     * @param res
     */
    public void zdyDownXzspFile(String subFileUrl, HttpServletResponse res){

        GetObjectArgs objectArgs = GetObjectArgs
                .builder()
                .bucket(spcyMinioConstant.MINIO_BUCKET_XZXK)
                .object(subFileUrl)
                .build();
        try (InputStream stream = this.xzspMinioClient().getObject(objectArgs)){
            byte[] bf = new byte[1024];
            int length;

            res.setContentType(Util.getContenTypeByWjhz(Util.getWjHz(subFileUrl)));
            res.setCharacterEncoding("UTF-8");
            OutputStream outputStream = res.getOutputStream();
            // 输出文件
            while ((length = stream.read(bf)) > 0) {
                outputStream.write(bf, 0, length);
            }
            // 关闭输出流
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {
            throw new BusinessException("文件下载错误："+e.getMessage());
        }
    }

    /**
     * 根据文件桶和文件全路径获取文件流
     *
     * @param objectName 文件名
     * @return 文件流
     */
    public InputStream getXzspFileObject(String objectName) {
        String subFileUrl = this.XzspFileUrl(objectName);
        try {
            return this.xzspMinioClient().getObject(
                    GetObjectArgs.builder()
                            .bucket(spcyMinioConstant.MINIO_BUCKET_XZXK)
                            .object(subFileUrl)
                            .build());
        } catch (Exception e) {
//            throw new RuntimeException("根据文件名获取流失败!", e);
            log.error("根据文件名获取流失败！{}", e);
            return null;
        }
    }

    /**
     * 预览文件
     * @param fileName 文件存储路径
     * @return
     */
    public String previewXzspFile(String fileName){
        String subFileUrl = this.XzspFileUrl(fileName);

        // 查看文件地址
        GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs()
                .builder()
                .bucket(spcyMinioConstant.MINIO_BUCKET_XZXK)
                .object(subFileUrl)
                .method(Method.GET)
                .build();
        try {
            String url = this.xzspMinioClient().getPresignedObjectUrl(build);
            return url;
        } catch (Exception e) {
            return "";
//            throw new BusinessException("预览文件失败："+e.getMessage());
        }
    }

    // 获取行政审批 - 真实存储的路径
    public String XzspFileUrl(String objName){
        /** 文件后缀去掉大写 */
        String wjHz = Util.getWjHz(objName);

        /** 去掉字符串中关键字及前缀 */
        String subFileUrl = StringPatternUtils.removeSubstringWithSurroundingSlashes(objName, spcyMinioConstant.MINIO_BUCKET_XZXK);
        subFileUrl = this.getFileUrlRemoveFirstIndex(subFileUrl);

        /*int baseLength = spcyMinioConstant.MINIO_BUCKET_XZXK.length(); // 主目录文件长度
        String subFileUrl = StringUtils.substring(objName, baseLength + 2);*/

        /** 验证是否为大小写，验证去掉和不去掉大写，前后是否一致，不一致 + '/' */
        try {
            int dotIndex = subFileUrl.lastIndexOf('.');
            if (dotIndex != -1) {
                if (!wjHz.equals(subFileUrl.substring(dotIndex))){
                    subFileUrl = "/" + subFileUrl;
                }
            }
        }catch (Exception e){
            return subFileUrl;
        }

        return subFileUrl;
//        return StringPatternUtils.stringHzLowerCase(subFileUrl);
    }

    // 去除地址第一个斜杠
    public String getFileUrlRemoveFirstIndex(String fileName){
        try {
            // 一个字符为斜杠
            if (StringUtils.substring(fileName, 0, 1).equals("/")){
                return StringUtils.substring(fileName, 1);
            }else {
                return fileName;
            }

        }catch (Exception e){
            return fileName;
        }

    }
}

